
package com.hlkj.pay.app.merchant.ext.impl.helipay;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.annotation.Extension;
import com.hlkj.pay.app.merchant.ext.ChannelMerchantWithdrawExtPt;
import com.hlkj.pay.app.merchant.ext.MerchantExtConstant;
import com.hlkj.pay.app.merchant.ext.dto.payment.ChannelWithdrawContext;
import com.hlkj.pay.app.merchant.ext.impl.helipay.dto.HeliPayEatrxConfig;
import com.hlkj.pay.app.merchant.ext.impl.helipay.dto.eatrx.HeePayEatrxTransferQueryRes;
import com.hlkj.pay.app.merchant.ext.impl.helipay.dto.eatrx.HeePayEatrxTransferSubmitRes;
import com.hlkj.pay.app.merchant.ext.impl.helipay.dto.eatrx.HeliPayEatrxAppChannelParams;
import com.hlkj.pay.app.merchant.ext.impl.helipay.handler.HeliPayMerchantEatrxCommonParamsHandle;
import com.hlkj.pay.app.merchant.ext.impl.helipay.util.Des3;
import com.hlkj.pay.common.MerchantResultCode;
import com.hlkj.pay.dto.order.NotifyOrderWithdrawDto;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.infrastructure.model.order.OrderWithdrawDO;
import com.hlkj.pay.infrastructure.model.pay.ProviderChannelConfigDO;
import com.hlkj.pay.util.DateUtils;
import com.hlkj.pay.util.HttpRequestUtil;
import com.hlkj.pay.util.MerchantUtils;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2024/11/20 17:19
 */
@Slf4j
@Repository
@RequiredArgsConstructor
@Extension(bizId = MerchantExtConstant.CHANNEL_HELIPAY_VIR)
public class HeliPayMerchantWithdrawExtPt extends HeliPayMerchantEatrxCommonParamsHandle implements ChannelMerchantWithdrawExtPt {

    @Override
    public void submitChannelWithdraw(ChannelWithdrawContext channelTransferContext) {
        log.info("合利宝提交单笔提现 payOrderCode:{}", channelTransferContext.getOrderWithdraw().getPayOrderNo());
        CommonResult<HeliPayEatrxConfig> configCommonResult = heliPayEatrxConfig(channelTransferContext.getProviderChannelConfig(), channelTransferContext.isTest());
        if (!configCommonResult.isSuccess()) {
            channelTransferContext.setRemark(configCommonResult.getMsg());
            channelTransferContext.setProcessStatus(false);
            return;
        }
        HeliPayEatrxConfig heliPayEatrxConfig = configCommonResult.getData();
        Map<String, Object> params = new HashMap<>();
        OrderWithdrawDO orderWithdraw = channelTransferContext.getOrderWithdraw();
        HeliPayEatrxAppChannelParams eatrxAppChannelParams = heePayAppChannelParams(channelTransferContext.getMerchantAppChannelDO());
        params.put("userId", eatrxAppChannelParams.getUserId());
        params.put("outVirtualAccountNo", eatrxAppChannelParams.getVirtualAccountNo());
        params.put("bankCardId", eatrxAppChannelParams.getBankCardId());
        params.put("orderNum", orderWithdraw.getPayOrderNo());
        params.put("amount", MerchantUtils.bigDecimalToString2(orderWithdraw.getAmount()));
        params.put("remark", orderWithdraw.getRemark());
        params.put("password", channelTransferContext.getPassword());
        params.put("notifyUrl", channelTransferContext.getNotifyUrl());

        String url = url(channelTransferContext.isTest()) + "/ea/withdraw";
        try {
            // 再提交数据
            CommonResult<HeePayEatrxTransferSubmitRes> commonResult = withdrawRequest(params, url, HeePayEatrxTransferSubmitRes.class, heliPayEatrxConfig);
            if (!commonResult.isSuccess()) {
                channelTransferContext.setProcessStatus(false);
                channelTransferContext.setRemark(commonResult.getMsg());
                return;
            }
            HeePayEatrxTransferSubmitRes eatrxTransferSubmitRes = commonResult.getData();
            if (!eatrxTransferSubmitRes.success()) {
                channelTransferContext.setProcessStatus(false);
                channelTransferContext.setRemark(eatrxTransferSubmitRes.getRetMsg());
                return;
            }
            OrderWithdrawDO updateOrderWithdrawDO = new OrderWithdrawDO();
            updateOrderWithdrawDO.setBankCardId(eatrxAppChannelParams.getBankCardId());
            channelTransferContext.setUpdateOrderWithdraw(updateOrderWithdrawDO);
            updateOrderWithdrawDO.setChannelOrderNo(eatrxTransferSubmitRes.getSerialNumber());
            updateOrderWithdrawDO.setUserId(eatrxAppChannelParams.getUserId());
            switch (eatrxTransferSubmitRes.getStatus()) {
                case "FAIL":
                    updateOrderWithdrawDO.setStatus(MerchantEnum.PROCESS_STATUS.FAIL.getCode());
                    break;
                case "SUCCESS":
                    updateOrderWithdrawDO.setStatus(MerchantEnum.PROCESS_STATUS.SUCCESS.getCode());
                    break;
                default:
                    updateOrderWithdrawDO.setStatus(MerchantEnum.PROCESS_STATUS.DOING.getCode());
            }
        }
        catch (Exception e) {
            channelTransferContext.setProcessStatus(false);
            channelTransferContext.setRemark(e.getMessage());
        }
    }

    @Override
    public CommonResult<NotifyOrderWithdrawDto> orderWithdrawStatusParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        String response = HttpRequestUtil.requestBodyParams(request);
        log.info("合利宝收到提现回调,参数数据为 response:{}", response);
        CommonResult<NotifyOrderWithdrawDto> payOrderDOCommonResult = CommonResult.success();
        try {
            CommonResult<HeliPayEatrxConfig> commonResult = heliPayEatrxConfig(providerChannelConfigDO, false);
            Map<String, String> params = JsonUtils.parseObject(response, Map.class);
            String merchantNo = params.get("merchantNo");
            String data = params.get("data");
            String sign = params.get("sign");
            String source = merchantNo + "&" + data;
            HeliPayEatrxConfig heliPayConfig = commonResult.getData();
            String responseData = Des3.decode(heliPayConfig.getWithdrawDes3Key(), data);
            HeePayEatrxTransferQueryRes eatrxTransferQueryRes = JsonUtils.parseObject(responseData, HeePayEatrxTransferQueryRes.class);
            // 配置转换
            NotifyOrderWithdrawDto notifyOrderWithdrawDto = new NotifyOrderWithdrawDto();
            notifyOrderWithdrawDto.setCallBackBody(responseData);
            notifyOrderWithdrawDto.setPayOrderNo(eatrxTransferQueryRes.getOrderNum());
            notifyOrderWithdrawDto.setChannelOrderNo(eatrxTransferQueryRes.getSerialNumber());
            switch (eatrxTransferQueryRes.getStatus()) {
                case "FAIL":
                    notifyOrderWithdrawDto.setStatus(MerchantEnum.PROCESS_STATUS.FAIL);
                    break;
                case "SUCCESS":
                    notifyOrderWithdrawDto.setStatus(MerchantEnum.PROCESS_STATUS.SUCCESS);
                    break;
                default:
                    notifyOrderWithdrawDto.setStatus(MerchantEnum.PROCESS_STATUS.DOING);
            }
            if (StringUtils.hasText(eatrxTransferQueryRes.getCompleteDate())) {
                try {
                    notifyOrderWithdrawDto.setSuccessTime(DateUtils.shanghaiDate(eatrxTransferQueryRes.getCompleteDate(), "yyyy-MM-dd HH:mm:ss"));
                }
                catch (Exception e) {
                    log.error("合利宝提现订单查询返回 时间格式化错误 dateTime:{},message:{}", eatrxTransferQueryRes.getCompleteDate(), e.getMessage());
                }
            }
            payOrderDOCommonResult.setData(notifyOrderWithdrawDto);
        }
        catch (Exception e) {
            e.printStackTrace();
            payOrderDOCommonResult.setCode(MerchantResultCode.MERCHANT_CHANNEL_CALLBACK_SIGN_ERROR.getCode());
        }
        log.info("合利宝收到提现回调,解析后的订单数据为 payOrderDO:{}", JsonUtils.toJsonString(payOrderDOCommonResult));
        return payOrderDOCommonResult;
    }

    @Override
    public void queryChannelWithdraw(ChannelWithdrawContext channelTransferContext) {
        log.info("合利宝单笔提现查询 payOrderCode:{}", channelTransferContext.getOrderWithdraw().getPayOrderNo());
        CommonResult<HeliPayEatrxConfig> configCommonResult = heliPayEatrxConfig(channelTransferContext.getProviderChannelConfig(), channelTransferContext.isTest());
        if (!configCommonResult.isSuccess()) {
            channelTransferContext.setRemark(configCommonResult.getMsg());
            channelTransferContext.setProcessStatus(false);
            return;
        }
        HeliPayEatrxConfig heliPayEatrxConfig = configCommonResult.getData();
        Map<String, Object> params = new HashMap<>();
        OrderWithdrawDO orderWithdraw = channelTransferContext.getOrderWithdraw();
        HeliPayEatrxAppChannelParams heliPayEatrxAppChannelParams = heePayAppChannelParams(channelTransferContext.getMerchantAppChannelDO());
        params.put("userId", heliPayEatrxAppChannelParams.getUserId());
        params.put("orderNum", orderWithdraw.getPayOrderNo());
        String url = url(channelTransferContext.isTest()) + "/ea/withdrawQuery";
        try {
            // 再提交数据
            CommonResult<HeePayEatrxTransferQueryRes> commonResult = withdrawRequest(params, url, HeePayEatrxTransferQueryRes.class, heliPayEatrxConfig);
            if (!commonResult.isSuccess()) {
                channelTransferContext.setProcessStatus(false);
                channelTransferContext.setRemark(commonResult.getMsg());
                return;
            }
            HeePayEatrxTransferQueryRes eatrxTransferQueryRes = commonResult.getData();
            if (!eatrxTransferQueryRes.success()) {
                channelTransferContext.setProcessStatus(false);
                channelTransferContext.setRemark(eatrxTransferQueryRes.getRetMsg());
                return;
            }
            OrderWithdrawDO updateOrderWithdraw = new OrderWithdrawDO();
            channelTransferContext.setUpdateOrderWithdraw(updateOrderWithdraw);
            updateOrderWithdraw.setChannelOrderNo(eatrxTransferQueryRes.getSerialNumber());
            switch (eatrxTransferQueryRes.getStatus()) {
                case "FAIL":
                    updateOrderWithdraw.setStatus(MerchantEnum.PROCESS_STATUS.FAIL.getCode());
                    break;
                case "SUCCESS":
                    updateOrderWithdraw.setStatus(MerchantEnum.PROCESS_STATUS.SUCCESS.getCode());
                    break;
                default:
                    updateOrderWithdraw.setStatus(MerchantEnum.PROCESS_STATUS.DOING.getCode());
            }
            if (StringUtils.hasText(eatrxTransferQueryRes.getCompleteDate())) {
                try {
                    updateOrderWithdraw.setSuccessTime(DateUtils.shanghaiDate(eatrxTransferQueryRes.getCompleteDate(), "yyyy-MM-dd HH:mm:ss"));
                }
                catch (Exception e) {
                    log.error("合利宝提现订单查询返回 时间格式化错误 dateTime:{},message:{}", eatrxTransferQueryRes.getCompleteDate(), e.getMessage());
                }
            }
            updateOrderWithdraw.setMessage(eatrxTransferQueryRes.getDescription());
        }
        catch (Exception e) {
            channelTransferContext.setProcessStatus(false);
            channelTransferContext.setRemark(e.getMessage());
        }
    }

    @Override
    public String callBackResponse(CommonResult commonResult) {
        if (commonResult.isSuccess()) {
            return "success";
        }
        return commonResult.getMsg();
    }
}
